#!/usr/bin/python3
# coding：utf-8
try:
    import do
except:
    from mySQL import do
import datetime
import json
import copy


def obj_to_dict(obj):
    if isinstance(obj, datetime.datetime):
        return obj.strftime("%Y-%m-%d %H:%M:%S")
    elif isinstance(obj, map):
        return [obj_to_dict(item) for item in obj]
    elif hasattr(obj, '__dict__'):
        dictObj = copy.deepcopy(obj.__dict__)
        for name in dictObj:
            dictObj[name] = obj_to_dict(dictObj[name])
        return dictObj
    elif isinstance(obj, tuple) or isinstance(obj, list):
        return [obj_to_dict(item) for item in obj]       
    return obj


class User:
    def __init__(self, sqlUserOrID):
        if sqlUserOrID is None:
            pass
        sqlUser = sqlUserOrID
        if isinstance(sqlUserOrID, int):
            sqlUser = do.getUserByID(sqlUserOrID) if sqlUserOrID > 0 else [sqlUserOrID, None, None, None, None]
        self.id = sqlUser[0]
        self.name = sqlUser[1]
        self.password = sqlUser[2]
        self.email = sqlUser[3]
        self.state = sqlUser[4]

    def to_dict(self):
        return self.__dict__

    def updateFromDatabase(self):
        user = User(do.getUserByID(self.id))
        if user is not None:
            self = user
        return self

    def updateToDatabase(self):
        do.updateUserByObj(self);
        return self.updateFromDatabase()

    def updateFromDict(self, dict_obj):
        self.__dict__.update(dict_obj)
        return self


class Sensor:
    def __init__(self, sqlSensor):
        if sqlSensor is None:
            pass
        self.id = sqlSensor[0]
        self.d_id = sqlSensor[1]
        self.name = sqlSensor[2]
        self.value = sqlSensor[3]
        self.datetime = sqlSensor[4].strftime("%Y-%m-%d %H:%M:%S")
        self.unit = sqlSensor[5]
        self.max = sqlSensor[6]
        self.min = sqlSensor[7]
        self.description = sqlSensor[8]
        self.state = sqlSensor[9]
        self.alarm = "正常" if self.max >= self.value >= self.min  else "报警"
        self.history = None

    def to_dict(self):
        return self.__dict__

    def getHistory(self, page_id, rows, timeStart=None):
        self.history = do.getHistoryBySensorID(self.id, page_id, rows)
        return self.history

    def getAlarms(self, page_id, rows, timeStart=None):
        self.history = do.getAlarmBySensorID(self.id, page_id, rows)
        return self.history

    def updateFromDatabase(self):
        sensor = Sensor(do.getSensorByID(self.id))
        if sensor is not None:
            self = sensor
        return self

    def updateToDatabase(self):
        do.updateSensorByObj(self);
        return self.updateFromDatabase();


class Device:
    def __init__(self, sqlDeviceOrId):  # id,name,address,state,serial,time
        sqlDevice = sqlDeviceOrId if not isinstance(sqlDeviceOrId, int) else do.getDeviceByID(sqlDeviceOrId)
        self.id = sqlDevice[0]
        self.name = sqlDevice[1]
        self.type = sqlDevice[2]
        self.address = sqlDevice[3]
        self.serial = sqlDevice[4]
        self.state = sqlDevice[5]
        self.description = sqlDevice[6]
        self.datetime = sqlDevice[7].strftime("%Y-%m-%d %H:%M:%S")
        self.users = None  # self.getUsers()
        self.sensors = self.getSensors()

    def getUsers(self):
        sqlUsers = do.getUsersByDeviceID(self.id)
        self.users = list(map(lambda item: User(item), sqlUsers)) if sqlUsers is not None else None
        return self.users

    def getSensors(self):
        sqlSensors = do.getActiveSensorsByDeviceID(self.id)
        self.sensors = list(map(lambda item: Sensor(item), sqlSensors)) if sqlSensors is not None else None
        return self.sensors

    def getAllSensors(self):
        sqlSensors = do.getSensorsByDeviceID(self.id)
        self.sensors = list(map(lambda item: Sensor(item), sqlSensors)) if sqlSensors is not None else None
        return self.sensors

    def updateSensorsHistory(self, page_id=1, rows=10):
        for item in self.sensors:
            item.getHistory(page_id, rows)
        return self

    def updateSensorsAlarm(self, page_id=1, rows=10):
        for item in self.sensors:
            item.getAlarms(page_id, rows)
        return self

    def to_dict(self):
        dictObj = copy.deepcopy(self.__dict__)
        dictObj["users"] = [item.to_dict() for item in self.users] if self.users is not None else None     
        dictObj["sensors"] = [item.to_dict() for item in self.sensors] if self.sensors is not None else None
        return dictObj


class UserDevicesManage:
    def __init__(self, nameOrID, password=None):
        sqlUser = do.getUserByNamePassword(nameOrID, password) if password is not None else do.getUserByID(nameOrID)
        self.user = User(sqlUser) if sqlUser is not None else None
        self.devices = None
        self.deviceCount = self.getDeviceCount()

    def to_dict(self):
        dictObj = copy.deepcopy(self.__dict__)
        dictObj["user"] = self.user.to_dict() if self.user is not None else None
        dictObj["devices"] = [item.to_dict() for item in self.devices] if self.devices is not None else None
        return dictObj

    def getDevicesAtPage(self, page_id, count):
        if self.user is None:
            return None
        sqlDevices = do.getDevicesByUserIDAtPage(self.user.id, page_id, count)
        self.devices = list(map(lambda item: Device(item), sqlDevices)) if sqlDevices is not None else None
        return self.devices

    def getDeviceCount(self):
        if self.user is None:
            return 0
        self.deviceCount = do.getDeviceCountByUserID(self.user.id)
        return self.deviceCount


def getAllUsersObj():
    sqlUsers = do.getUsers()
    return list(map(lambda item: User(item), sqlUsers)) if sqlUsers is not None else None


if __name__ == '__main__':
    userDevices = UserDevicesManage("jure", "liulong")
    userDevices.getDevicesAtPage(1, 25)
    userDevices.devices[0].getSensors()
    obj = userDevices.user
    print(obj_to_dict(obj))
    obj.state = "active"
    print(obj_to_dict(obj.updateToDatabase()))
    obj = userDevices.devices[0].sensors[0];
    print(obj_to_dict(obj))
    obj.state = "active"
    print(obj_to_dict(obj.updateToDatabase()))

    userManage = UserDevicesManage(10)
    print(userManage.to_dict())
